/*
 * Salmane y Alberto:
 */
package infb.actions;

import javax.naming.NamingException;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import infb.forms.*;
import infb.dao.*;
import infb.errores.*;
import infb.modelo.*;
import infb.modelo.Pacientes;
import infb.util.Paginador;
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.TreeMap;
import javax.ejb.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.struts.upload.FormFile;

public class GestionPacientesAction extends Action {

 /*
     * Metodo guardar la foto en un archivo
     */
    private void AlmacenarFoto(FormFile foto, String nombreArchivo) {
            String path = "C:/workspace/InfB/GestionHospitalaria/web/fotos/pacientes/"+nombreArchivo;
            try {
                File f = new File(path);
                if (makeSureDirectoryExists(parent(f))) {
                    FileOutputStream out = new FileOutputStream(f);
                    out.write(foto.getFileData());
                    out.flush();
                    out.close();
                }
            }
            catch (Exception ex) {
                throw new GestionHospitalariaException("Error: No se pudo almacenar correctamente la foto " + ex.getMessage());
            }
    }

    /**
    * Devuelve la ruta padre del subdirectorio actual
    * @param File --> El archivo del cual se quiere sacar su directorio o directorio padre
    * @return File --> Crea un archivo con la ruta del directorio padre
    */
    private File parent(File f) {
        String dirname = f.getParent();
        if (dirname == null ) {
            return new File(File.separator);
        }
        return new File(dirname);
    }

    /**
    * Crear un subdirectorio si este no existe
    * @param dir --> El path del archivo (dirección + nombre)
    * @return True -> Existe o se ha creado False --> No existe y no se ha podido crear
    */
    private boolean makeSureDirectoryExists(File dir) {
        if (!dir.exists()) {
            if (makeSureDirectoryExists(parent(dir)))
                dir.mkdir();
            else
                return false ;
        }
        return true ;
    }

    /*
     * Metodo interno destinado a la creacion de pacientes
     */
    private ActionForward prepararInsercion(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            // Control basico de seguridad: solo los administradores
            // tendran privilegios para crear pacientes
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(!perfil.equalsIgnoreCase("administrador")){
                peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                peticion.setAttribute("urlRetorno", "javascript:history.back()");
                return mapping.findForward("error");
            }

            Context contexto = new InitialContext();
            MedicosInterfaz medicos = (MedicosInterfaz) contexto.lookup("MedicosEJB");

            List listaMedicos = medicos.findAll();
            sesion.setAttribute("listaMedicos", listaMedicos);

            sesion.removeAttribute("objetoModificar");

            return mapping.findForward("preparar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO MedicosInterfaz " + ne.getMessage());
        }
    }

    private ActionForward cargarPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            PacientesInterfaz pacientes = (PacientesInterfaz) contexto.lookup("PacientesEJB");
            MedicosInterfaz medicos = (MedicosInterfaz) contexto.lookup("MedicosEJB");

            Long idPaciente = new Long(peticion.getParameter("id"));
            Pacientes paciente = pacientes.find(idPaciente);

            // Control basico para evitar que un paciente pueda cargar los datos
            // de otra persona
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(perfil.equalsIgnoreCase("paciente")){
                Pacientes p=(Pacientes)sesion.getAttribute("usuario");
                if(!idPaciente.toString().equalsIgnoreCase(p.getId().toString())){
                    peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                    peticion.setAttribute("urlRetorno", "javascript:history.back()");
                    return mapping.findForward("error");
                }
            }

            if (paciente == null) {
                throw new GestionHospitalariaException("Error: El identificador del paciente pasado como parámetro no existe");
            }

            List listaMedicos = medicos.findAll();
            sesion.setAttribute("listaMedicos", listaMedicos);
            peticion.setAttribute("dniMedico", paciente.getMedico());
            String fechaCad=null;
            Date fecha = paciente.getFechaNacimiento();
            if (fecha!=null) {
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
                fechaCad = sdf.format(fecha);
            } 
            sesion.setAttribute("fechaCad",fechaCad);
            // Incorporamos objetos a la sesion

            sesion.setAttribute("objetoModificar", paciente);

            // Redirigimos hacia la vista
            return mapping.findForward("cargar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar alguna de las clases DAO implicadas en el metodo cargarPacientes" + ne.getMessage());
        } catch (NumberFormatException nfe) {
            throw new GestionHospitalariaException("Error: El identificador del paciente debe ser una cadena de caracteres " + nfe.getMessage());
        }
    }

    private ActionForward crearPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException, NamingException {
        try {
            // Control basico para evitar que un paciente pueda cargar los datos
            // de otra persona
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(!perfil.equalsIgnoreCase("administrador")){
                peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                peticion.setAttribute("urlRetorno", "javascript:history.back()");
                return mapping.findForward("error");
            }

            Context contexto = new InitialContext();
            PacientesInterfaz pacienteInterfaz = (PacientesInterfaz) contexto.lookup("PacientesEJB");
            MedicosInterfaz medicos = (MedicosInterfaz) contexto.lookup("MedicosEJB");
            SetPacientesForm formularioPaciente = (SetPacientesForm) form;

            Pacientes paciente = new Pacientes();
            paciente.setTarjetaSanitaria(formularioPaciente.getTarjetaSanitaria());
            paciente.setNombre(formularioPaciente.getNombre());
            paciente.setApellido1(formularioPaciente.getApellido1());
            paciente.setIdentificacion(formularioPaciente.getIdentificacion());
            paciente.setApellido2(formularioPaciente.getApellido2());
            paciente.setTelefono(formularioPaciente.getTelefono());
            paciente.setMail(formularioPaciente.getMail());
            paciente.setSexo(formularioPaciente.getSexo());
            paciente.setGrupoSanguineo(formularioPaciente.getGrupoSanguineo());
            paciente.setDireccion(formularioPaciente.getDireccion());
            paciente.setLocalidad(formularioPaciente.getLocalidad());
            paciente.setProvincia(formularioPaciente.getProvincia());
            paciente.setObservaciones(formularioPaciente.getObservaciones());
            String foto;
            String identificacion=paciente.getIdentificacion();
            FormFile fotoFile = formularioPaciente.getFoto();
            if (fotoFile.getFileSize()== 0){
                foto="sin_imagen.jpg";
            }else{
                foto=identificacion+"_"+fotoFile.getFileName();
                AlmacenarFoto(fotoFile,foto);
            }
            paciente.setFoto(foto);
            fotoFile.destroy();

            /* Ejemplo interesante */

            Medicos medico = medicos.find(formularioPaciente.getMedico());
            paciente.setMedico(medico);

            paciente.setPassword(formularioPaciente.getPassword());


//            String fechaCad = formularioPaciente.getFechaNacimiento();
//            if (fechaCad.equals("")) {
//                SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
//                Date fecha = sdf.parse(fechaCad);
//                paciente.setFechaNacimiento(fecha);
//            }
            String fechaCad = formularioPaciente.getFechaNacimiento();
            Date fecha;
            if (!fechaCad.equals("")) {
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
                fecha = sdf.parse(fechaCad);
            } else {
                fecha = null;
            }
            paciente.setFechaNacimiento(fecha);
            String alturaCad = formularioPaciente.getAltura();
            if (!alturaCad.equals("")) {
                Short altura = Short.valueOf(alturaCad);
                paciente.setAltura(altura);
            }
            String pesoCad = formularioPaciente.getPeso();
            if (!pesoCad.equals("")) {
                BigDecimal peso = new BigDecimal(pesoCad);
                paciente.setPeso(peso);
            }
            pacienteInterfaz.create(paciente);
            peticion.setAttribute("mensaje", "El paciente ha sido insertado correctamente");
            peticion.setAttribute("urlRetorno", "index.jsp");

            return mapping.findForward("ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo insertar correctamente el paciente en la Base de Datos " + e.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la modificacion de pacientes
     */
    private ActionForward modificarPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            Context contexto = new InitialContext();
            PacientesInterfaz pacientes = (PacientesInterfaz) contexto.lookup("PacientesEJB");
            SetPacientesForm formularioDatos = (SetPacientesForm) form;

            HttpSession sesion = peticion.getSession();
            Pacientes paciente = pacientes.find(((Pacientes) sesion.getAttribute("objetoModificar")).getId());

            paciente.setTarjetaSanitaria(formularioDatos.getTarjetaSanitaria());
            paciente.setNombre(formularioDatos.getNombre());
            paciente.setApellido1(formularioDatos.getApellido1());
            paciente.setApellido2(formularioDatos.getApellido2());
            paciente.setIdentificacion(formularioDatos.getIdentificacion());
            paciente.setTelefono(formularioDatos.getTelefono());
            paciente.setMail(formularioDatos.getMail());
            paciente.setSexo(formularioDatos.getSexo());
            paciente.setGrupoSanguineo(formularioDatos.getGrupoSanguineo());
            paciente.setDireccion(formularioDatos.getDireccion());
            paciente.setLocalidad(formularioDatos.getLocalidad());
            paciente.setProvincia(formularioDatos.getProvincia());
            paciente.setObservaciones(formularioDatos.getObservaciones());
            String foto;
            String identificacion=paciente.getIdentificacion();
            FormFile fotoFile = formularioDatos.getFoto();
            if (fotoFile.getFileSize()== 0){
                foto="sin_imagen.jpg";
            }else{
                foto=identificacion+"_"+fotoFile.getFileName();
                AlmacenarFoto(fotoFile,foto);
            }
            paciente.setFoto(foto);
            fotoFile.destroy();

            String alturaCad = formularioDatos.getAltura();
            if (!alturaCad.equals("")) {
                Short altura = Short.valueOf(alturaCad);
                paciente.setAltura(altura);
            }
            String pesoCad = formularioDatos.getPeso();
            if (!pesoCad.equals("")) {
                BigDecimal peso = new BigDecimal(pesoCad);
                paciente.setPeso(peso);
            }
            String fechaCad = formularioDatos.getFechaNacimiento();
            Date fecha;
            if (!fechaCad.equals("")) {
                SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy");
                fecha = sdf.parse(fechaCad);
            } else {
                fecha = null;
            }
            paciente.setFechaNacimiento(fecha);


            /* Establecimiento del medico */
            MedicosInterfaz medicos = (MedicosInterfaz) contexto.lookup("MedicosEJB");
            Medicos medico = medicos.find(formularioDatos.getMedico());
            paciente.setMedico(medico);

            paciente.setPassword(formularioDatos.getPassword());
            pacientes.edit(paciente);

            String perfil = (String) sesion.getAttribute("perfil");
            if (perfil.equals("paciente")) {
                Pacientes usuario = (Pacientes) sesion.getAttribute("usuario");
                if (usuario.getId().equals(paciente.getId())) {
                    sesion.setAttribute("usuario", paciente);
                }
            }
            sesion.removeAttribute("fechaCad");
            sesion.removeAttribute("objetoModificar");
            peticion.setAttribute("urlRetorno", "javascript:history.go(-3)");

            return mapping.findForward("ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo modificar correctamente el paciente en la Base de Datos " + e.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la eliminacion de pacientes
     */
    private ActionForward eliminarPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {
        try {
            // Control basico de seguridad: la eliminacion de pacientes esta restringida a administradores
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(!perfil.equalsIgnoreCase("administrador")){
                peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                peticion.setAttribute("urlRetorno", "javascript:history.back()");
                return mapping.findForward("error");
            }

            Context contexto = new InitialContext();
            PacientesInterfaz pacientes = (PacientesInterfaz) contexto.lookup("PacientesEJB");

            PacientesInterfaz pacienteInterfaz = (PacientesInterfaz) contexto.lookup("PacientesEJB");
            Pacientes paciente;

            String[] arrayNombres = peticion.getParameterValues("id");
            List listaNombres = new ArrayList();
            listaNombres = arrayToList(arrayNombres);

            for (int i = 0; i < listaNombres.size(); i++) {
                //  System.out.print(Long.getLong((String)listaNombres.get(i)));
                Long pac = Long.valueOf((String) listaNombres.get(i));
                paciente = pacienteInterfaz.find(pac);
                pacienteInterfaz.remove(paciente);
            }

            return mapping.findForward("ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        } catch (Exception e) {
            throw new GestionHospitalariaException("Error: No se pudo eliminar correctamente el paciente de la Base de Datos " + e.getMessage());
        }

    }

    /*
     * Metodo interno destinado al listado de pacientes
     */
    private ActionForward listarPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {

        try {
            // Control basico de seguridad: el listado de pacientes esta restringido a medicos y administradores
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(!perfil.equalsIgnoreCase("administrador") || !perfil.equalsIgnoreCase("medico")){
                peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                peticion.setAttribute("urlRetorno", "javascript:history.back()");
                return mapping.findForward("error");
            }
            Context contexto = new InitialContext();
            PacientesInterfaz pacienteInterfaz = (PacientesInterfaz) contexto.lookup("PacientesEJB");
            Paginador p = null;

            List listaNombres = null;

            if (perfil.equals("medico")) {
                Medicos medico = (Medicos) sesion.getAttribute("usuario");
                p = new Paginador(pacienteInterfaz.buscarPorMedico(medico), peticion);
                String[] arrayNombres = peticion.getParameterValues("nTargeta");
                listaNombres = arrayToList(arrayNombres);
            } else {
                p = new Paginador(pacienteInterfaz.findAll(), peticion);

            }
            List listaPacientes = p.getResultadosPaginados();
            peticion.setAttribute("lista_nombres", listaNombres);
            peticion.setAttribute("lista_pacientes", listaPacientes);
            peticion.setAttribute("navegacion", p.getNavegacion());
            peticion.setAttribute("informacion", p.getMetaInformacion());

        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        }
        return mapping.findForward("listar_ok");
    }

    /*
     * Metodo interno destinado a ver datos de un paciente
     */
    private ActionForward verPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException, NamingException {
        try {
            Context contexto = new InitialContext();
            PacientesInterfaz pacientes = (PacientesInterfaz) contexto.lookup("PacientesEJB");

            String parametro = (String) peticion.getParameterNames( ).nextElement();

            Long idPaciente = null;
            Pacientes paciente = null;
            String id = null, tsPaciente=null;

            if (parametro.equals("id")) {//entramos con id
                id=(String)peticion.getParameter("id");
                idPaciente = new Long(id);
                paciente = pacientes.find(idPaciente);
            } else {
                tsPaciente = peticion.getParameter("ts");
                paciente = pacientes.buscarPorTarjetaSanitaria(tsPaciente);
            }

            // Control basico para evitar que un paciente pueda ver los datos
            // de otra persona
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(perfil.equalsIgnoreCase("paciente")){
                Pacientes p=(Pacientes)sesion.getAttribute("usuario");
                if(parametro.equals("id")){
                   if(!id.equalsIgnoreCase(p.getId().toString())){
                        peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                        peticion.setAttribute("urlRetorno", "javascript:history.back()");
                        return mapping.findForward("error");
                   }
                }else{
                   if(!p.getTarjetaSanitaria().equalsIgnoreCase(tsPaciente)){
                        peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                        peticion.setAttribute("urlRetorno", "javascript:history.back()");
                        return mapping.findForward("error");
                    }
                }
            }

            if (paciente == null) {
                throw new GestionHospitalariaException("Error: El identificador del paciente pasado como parámetro no existe");
            }

            // Incorporamos el bean en la sesion
            if(perfil.equals("medico")){
                System.out.println("pacienteCita");
                sesion.setAttribute("pacienteC",paciente);
            }
            peticion.setAttribute("paciente", paciente);
            // Redirigimos hacia la vista
            return mapping.findForward("ver_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        } catch (NumberFormatException nfe) {
            throw new GestionHospitalariaException("Error: El identificador del paciente debe ser una cadena " + nfe.getMessage());
        }
    }

    /*
     * Metodo interno destinado a la busqueda de pacientes
     */
    private ActionForward buscarPacientes(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException {

        try {
            // Control basico de seguridad: la busqueda de pacientes esta limitada a medicos y administradores
            HttpSession sesion=peticion.getSession();
            String perfil=(String)sesion.getAttribute("perfil");
            if(!perfil.equalsIgnoreCase("administrador") && !perfil.equalsIgnoreCase("medico")){
                peticion.setAttribute("claveMensajeError", "msg.error.no_autorizado");
                peticion.setAttribute("urlRetorno", "javascript:history.back()");
                return mapping.findForward("error");
            }

            Context contexto = new InitialContext();
            PacientesInterfaz pacientesInterfaz = (PacientesInterfaz) contexto.lookup("PacientesEJB");

            String buscar = peticion.getParameter("buscar");
           
            Paginador p=null;
            if (buscar != null && buscar.equals("1")) {
                // Obtenemos los parametros de busqueda
                BuscarPacientesForm formularioBusqueda = (BuscarPacientesForm) form;
                String tarjetaSanitaria = formularioBusqueda.getTarjetaSanitaria();
                String identificacion = formularioBusqueda.getIdentificacion();
                String apellido1 = formularioBusqueda.getApellido1();
                String apellido2 = formularioBusqueda.getApellido2();
                String nombre = formularioBusqueda.getNombre();
                if (perfil.equals("medico")) {//Muestra solo los pacientes correspondientes a su medico
                    Medicos medico = (Medicos) sesion.getAttribute("usuario");
                     p = new Paginador(pacientesInterfaz.buscarPorMedico(medico), peticion);
                   
                 }
                else{

                // Almacenamos el resultado de la consulta en la peticion
                 p = new Paginador(pacientesInterfaz.busquedaAvanzada(tarjetaSanitaria, identificacion, apellido1, apellido2, nombre), peticion);
                }
                List listaPacientes = p.getResultadosPaginados();
                if (listaPacientes != null) {
                    peticion.setAttribute("lista_pacientes", listaPacientes);
                    peticion.setAttribute("navegacion", p.getNavegacion());
                    peticion.setAttribute("informacion", p.getMetaInformacion());
                }
            }

            return mapping.findForward("buscar_ok");
        } catch (NamingException ne) {
            throw new GestionHospitalariaException("Error: No se pudo cargar la clase DAO PacientesInterfaz " + ne.getMessage());
        }
    }

    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest peticion, HttpServletResponse respuesta) throws GestionHospitalariaException, NamingException {

        String delegaEn = mapping.getParameter();
        HttpSession sesion = peticion.getSession();

        /*-----------------------------------------*/
        /* Control de autenticacion y autorizacion */
        /*-----------------------------------------*/
        String perfil = (String) sesion.getAttribute("perfil");
        if (perfil == null) {
            peticion.setAttribute("urlRetorno", "index.jsp");
            peticion.setAttribute("claveMensajeError", "msg.error.no_autenticado");
            return mapping.findForward("error");
        }

        if (delegaEn.equalsIgnoreCase("crear")) {
            // codigo para crear un paciente
            return this.crearPacientes(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("cargar")) {

            // cargar los datos de un paciente
            return this.cargarPacientes(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("preparar_insercion")) {
            // cargar los datos de un paciente
            return this.prepararInsercion(mapping, form, peticion, respuesta);

        } else if (delegaEn.equalsIgnoreCase("modificar")) {
            // codigo para modificar un paciente
            return this.modificarPacientes(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("eliminar")) {
            // codigo para eliminar un paciente
            return this.eliminarPacientes(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("ver")) {
            // codigo para ver un paciente
            return this.verPacientes(mapping, form, peticion, respuesta);
        } else if (delegaEn.equalsIgnoreCase("listar")) {
            // codigo para listar pacientes
            return this.listarPacientes(mapping, form, peticion, respuesta);
        } else {
            return this.buscarPacientes(mapping, form, peticion, respuesta);
        }
    }

    private <T> List<T> arrayToList(T[] array) {
        List lista = new ArrayList<T>();
        if (array != null) {
            for (int i = 0; i < array.length; i++) {
                lista.add(array[i]);
            }
        }
        return lista;
    }
}
